<?php
/*=============================================================================
|| ##################################################################
||	phpFoX Konsort
|| ##################################################################
||	
||	Copyright		: (C) 2005-2007 PHPFOX Limited a Reality Fox Creation
||	Contact			: info@phpfox.com
||
||	- phpFoX and all of its source code and files are protected by Copyright Laws. 
||
||	- The license for phpFoX permits you to install this software on a single domain (.com, .org, .net, etc.). 
||
||	- You may also not remove this copyright screen which shows the copyright information and credits for phpFoX (RealityFOX Creations). 
||
||	- phpFoX Konsort is NOT a FREE software - http://www.phpfox.com/license/
||
|| ##################################################################
=============================================================================*/

/* $File: ./include/modules/Quiz/classes/PhpFox_ServiceQuiz.class.php, $Author:  $ */



/** Service for working with quizzes
 * 
 *   
 * @version $Id: PhpFox_ServiceQuiz.class.php 297 2008-02-07 15:05:58Z phpfoxsv $
 * @package module.quiz
 */
class PhpFox_Mod_Quiz_ServiceQuiz extends BaseService
{
    /** Get list of quizzes
     * 
     * @param array  $aCond     condition array
     * @param int    $iPage     page number
     * @param int    $iPageSize page size (row per page)
     * @param string $sSort     sorting order
     */
    function getQuizList($aCond, $iPage=0, $iPageSize=0, $sSort='', $sKeyField='')
	{
	    $oQuiz = $this->_oModule->getItem('Quiz');
	    
        $aMap = $oQuiz->aFields;
        $aFields = array();

        $sCond = $oQuiz->_parseCond($aCond, $aMap);
        $sSql = 'SELECT COUNT(*) FROM `'.$oQuiz->sTable.'` AS '.$oQuiz->sAlias.' WHERE '.$sCond;
        $iCnt = $oQuiz->oDb->getField($sSql);
        $aRows = array();
        if ($iCnt)
        {
            $sKeyField = $sKeyField ? $sKeyField : $oQuiz->sId;
            $iOffset = $oQuiz->_getOffset($iPage, $iPageSize, $iCnt);
            $sSql = 'SELECT '.$oQuiz->_joinFields($aMap, $aFields).', '.
                    '       AVG(score) AS avg_score, MAX(qz2.id) AS last_taken_id  '.
                    ' FROM `'.$oQuiz->sTable.'` AS qz '.
                    '   LEFT JOIN '.App::getT('quiz_2').' AS qz2 ON (qz.id = qz2.quizid) '.
                    ' WHERE '.$sCond.
                    ' GROUP BY qz.id '.
                    ($sSort?(' ORDER BY '.$sSort):'').
                    ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');
            $aRows = $oQuiz->oDb->getRows($sSql, true, $sKeyField);
        }
        return array($aRows, $iCnt);
	}
	
	/** Get quiz results for given user
	 * 
	 * @param PhpFox_Mod_Quiz_ItemQuiz       $oQuiz    quiz object
     * @param PhpFox_Mod_Account_ItemAccount $oUser    user object
	 */
	function getUserResults($oQuiz, $oUser)
    {
        $aRes = array();
        $oUserResult = $this->_oModule->getItem('UserResult');

	    if ($oUserResult->loadByCondition('quizid = '.$oQuiz->getId().' AND '.
                                          'user1 = "'.$oUser->aData['user'].'"'))
	    {
	        $aRes = $oUserResult->aData;
	        $oResult = $this->_oModule->getItem('Result');
	        list($aRes['results']) = $oResult->getList(array('id = '.$oUserResult->getId()));
	    }
	    return $aRes;
    }
	
	/** Add answers to quiz
	 * 
	 * @param PhpFox_Mod_Quiz_ItemQuiz       $oQuiz    quiz object
	 * @param array                          $aAnswers user's answers
	 * @param PhpFox_Mod_Account_ItemAccount $oUser    user object
	 * @return array result info
	 */
	function addAnswers($oQuiz, $aAnswers, $oUser)
	{
	    $oUserResult = $this->_oModule->getItem('UserResult');
	    if ($oUserResult->loadByCondition('quizid = '.$oQuiz->getId().
	                                ' AND user1 = "'.$oUser->aData['user'].'"'))
	    {
	        return false;
	    }
	    
	    $oQuestion = &$this->_oModule->getItem('Question');
	    /* @var $oQuestion PhpFox_Mod_Quiz_ItemQuestion */
	    list($aQuestions) = $oQuestion->getList(array('cid = '.$oQuiz->aData['id']));
	    
	    if(count($aQuestions) > count($aAnswers))
	    {
    	    $this->addErrors(App::format('Mod_Quiz.error.not_all_answers'));
    	    return false;
	    }
	    
	    $aResults = array();
	    $iCorrAnswers = 0;
	    foreach($aQuestions as $aQuestion)
	    {
            $aResults[] = array(
                'is_correct'  => ($aQuestion['answer'] == $aAnswers[$aQuestion['id']]),
                'question'    => $aQuestion['q1'],
                'user_answer' => $aAnswers[$aQuestion['id']],
                'corr_answer' => $aQuestion['answer'],
            );
            if (($aQuestion['answer'] == $aAnswers[$aQuestion['id']]))
            {
                $iCorrAnswers++;
            }
	    }
	    
	    //add result to db
        $fResult = count($aQuestions) ? $iCorrAnswers * 100 / count($aQuestions) : 0;
        $oUserResult = $this->_oModule->getItem('UserResult');
        $oUserResult->aData = array(
            'quizid' => $oQuiz->getId(),
            'user'   => $oQuiz->aData['user'],
            'user1'  => $oUser->aData['user'],
            'score'  => $fResult,
            'time'   => time(),
            'seen'   => '',
        );
        $iUserResultId = $oUserResult->insert();
        
        $oResult = $this->_oModule->getItem('Result');
        foreach($aResults as $aResult)
        {
            $oResult->aData = array(
                'id' => $iUserResultId,
                'q'  => $aResult['question'],
                'a1' => $aResult['user_answer'],
                'a2' => $aResult['corr_answer'],
            );
            $oResult->insert();
        }
        
        
        //update quiz data (player, score etc.)
        $oQuiz->aData['player'] = $oUser->aData['user'];
        $oQuiz->aData['points'] = $fResult;
        $oQuiz->aData['views']++;
        $oQuiz->update(array('player', 'points', 'views'));
        
        return $aResults;
	}

	/** Delete given quiz
	 * 
	 * @param int $iQuizId quiz ID
	 * @return bool true - quiz deleted succesfull, false - error occured
	 */
    function deleteQuiz($iQuizId)
    {
        $oQuiz = $this->_oModule->getItem('Quiz');
        if ($oQuiz->load($iQuizId))
        {
            //delete all questions
            $oQuiz->oDb->query('DELETE FROM '.App::getT('quiz').' WHERE cid = '.$oQuiz->getId());
            
            //delete all user's answer
            $oQuiz->oDb->query('DELETE FROM '.App::getT('quiz_1').' WHERE id IN '.
                               '  (SELECT id FROM '.App::getT('quiz_2').'  WHERE quizid = '.$oQuiz->getId().')');
            $oQuiz->oDb->query('DELETE FROM '.App::getT('quiz_2').' WHERE quizid = '.$oQuiz->getId());
            
            //delete quiz
            $oQuiz->delete($oQuiz->getId());
            $oSrvAcc = &App::getModuleService('Account', 'Account');
            $oSrvAcc->changeUserInfo($oSrvAcc->getByUsername($oQuiz->aData['user']), 'quiz',-1);            
            return true;
        }
        
        return false;
    }

    /** Approve quiz
     * 
     * @param int $iQuizId quiz ID
     * @return bool true - quiz approve, false - error occured
     */
    function approveQuiz($iQuizId)
    {
        $oQuiz = $this->_oModule->getItem('Quiz');
        if ($oQuiz->load($iQuizId))
        {
            $oQuiz->aData['type'] = '2'; //legacy magic number
            if ($oQuiz->update(array('type')))
            {
                return true;
            }
            else
            {
                $this->addErrors($oQuiz->getErrors());
            }
            
        }
        return false;
    }
    
    /** Is given user already passed quiz?
     * 
     * @param PhpFox_Mod_Account_ItemAccount $oUser   user object
     * @param int                            $iQuizId quiz ID
     * @return bool true - user already answered quiz, false - not take yet
     */
    function isPassedQuiz($oUser, $iQuizId)
    {
        if (!$oUser)
        {
            return false;
        }
        $iCnt = $oUser->oDb->getField('SELECT COUNT(*) FROM '.App::getT('quiz_2').
                                      '  WHERE quizid = '.$iQuizId.
                                      '    AND user1 = "'.$oUser->aData['user'].'"');
        return ($iCnt > 0);
    }
    
    /** Get list of results for quizz
     * 
     * @param int    $iQuizId   condition array
     * @param int    $iPage     page number
     * @param int    $iPageSize page size (row per page)
     * @param string $sSort     sorting order
     */
    function getQuizResultsList($iQuizId, $iPage=0, $iPageSize=0, $sSort='')
	{
	    $oUserResult = $this->_oModule->getItem('UserResult');
        $aCond = array('quizid' => ' = '.$iQuizId);
        return $oUserResult->getList($aCond, $iPage, $iPageSize, $sSort);
	}

	/** Creates new quiz
	 * 
	 * @param string                         $sTitle      quiz title
	 * @param array                          $aQuestions  quiz questions
	 * @param array                          $aAnswers    quiz question answer variants
	 * @param PhpFox_Mod_Account_ItemAccount $oUser       user account
	 * @return bool true - create succesfull, false - error occured
	 */
    function createQuiz($sTitle, $aQuestions, $aAnswers, $oUser)
    {
        
        $oTxt = App::newObject('Text');
        $oQuiz = $this->_oModule->getItem('Quiz');
        $oQuiz->aData = array(
            'user'  => $oUser->aData['user'],
            'title' => $oTxt->preParseText($sTitle),
            'time'  => time(),
            'views' => 0,
        );
        if ($iQuizId = $oQuiz->insert())
        {
            $oQuestion = $this->_oModule->getItem('Question');
            foreach($aQuestions as $iPos => $sQuestion)
            {
                if ($sQuestion)
                {
                    $oQuestion->aData = array(
                        'cid'    => $iQuizId,
                        'q1'     => $oTxt->preParseText($sQuestion),
                        'a1'     => $oTxt->preParseText($aAnswers[$iPos][1]),
                        'a2'     => $oTxt->preParseText($aAnswers[$iPos][2]),
                        'a3'     => $oTxt->preParseText($aAnswers[$iPos][3]),
                        'a4'     => $oTxt->preParseText($aAnswers[$iPos][4]),
                        'answer' => $oTxt->preParseText($aAnswers[$iPos][1]),
                    );
                    $oQuestion->insert();
                }
            }
            $oSrvAcc = &App::getModuleService('Account', 'Account');
            $oSrvAcc->changeUserInfo($oUser, 'quiz');            
            return true;
        }
        
        return false;
    }
    
    /** Get questions for quiz
     * 
     * @param int $iQuizId quiz ID
     */
    function getQuestions($iQuizId)
    {
        $oAnswer = &$this->_oModule->getItem('Question');
        $aCond = array('cid' => ' = '.$iQuizId);
        list($aQuestions) = $oAnswer->getList($aCond);
        return $aQuestions;
    }
    
    /** Callback handler on delete account
     * 
     * @param array $aParams event params ('oAcc' => $oAcc, 'aIds'=>$mAccIds)
     */
    function onDeleteAccount($aParams)
    {
        $aIds = $aParams['aIds'];
        if ($aIds)
        {
            $oAcc = $aParams['oAcc'];
            /* @var $oAcc PhpFox_Mod_Account_ItemAccount */
            
            $oQuiz = $this->_oModule->getItem('Quiz');
            /* @var $oQzui PhpFox_Mod_Account_ItemQuiz */
            
            foreach($aIds as $iId)
            {
                if ($oAcc->load($iId))
                {
                    $sUser = $oAcc->aData['user'];
                    
                    //delete user's quizzes
                    $aQuizIds = $oQuiz->oDb->getHash('SELECT id, id FROM `'.$oQuiz->sTable.'` '.
                                                     '  WHERE user = "'.$sUser.'"');
                    if ($aQuizIds) //member has quizzes
                    {
                        //delete question and answer
                        $sQuizIds = implode(',', $aQuizIds);
                        $oQuiz->oDb->query('DELETE FROM '.App::getT('quiz').' WHERE cid IN('.$sQuizIds.')');
                        
                        //get all answers from user's question or answere by user
                        $aQuizRes = $oQuiz->oDb->getHash('SELECT id, quizid FROM '.App::getT('quiz_2').
                                                         ' WHERE quizid IN ('.$sQuizIds.') '.
                                                         '    OR user = "'.$sUser.'" '.
                                                         '    OR user1 = "'.$sUser.'" ');
                        if ($aQuizRes) //delete quizzes result (for member's quizzes)
                        {
                            $sQuizRes = implode(',', $aQuizRes);
                            $oQuiz->oDb->query('DELETE FROM '.App::getT('quiz_1').
                                               ' WHERE id IN ('.$sQuizRes.')');
                        }
                    }
                    
                    //delete user's quizzes
                    $oQuiz->oDb->query('DELETE FROM '.App::getT('hot_quiz').
                                       ' WHERE user = "'.$sUser.'"');
                }
            }
        }
    }
}
?>